package cn.iocoder.yudao.module.worker.controller.app.clerk;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.util.ObjectUtil;
import cn.iocoder.yudao.framework.ip.core.utils.IPUtils;
import cn.iocoder.yudao.framework.security.core.annotations.PreAuthenticated;
import cn.iocoder.yudao.module.product.api.comment.ProductCommentApi;
import cn.iocoder.yudao.module.worker.api.category.CategoryApi;
import cn.iocoder.yudao.module.worker.api.category.dto.CategoryRespDTO;
import cn.iocoder.yudao.module.worker.controller.admin.category.vo.CategoryRespVO;
import cn.iocoder.yudao.module.worker.dal.dataobject.clerkfans.ClerkFansDO;
import cn.iocoder.yudao.module.worker.dal.dataobject.clerklevel.ClerkLevelDO;
import cn.iocoder.yudao.module.worker.enums.SexEnum;
import cn.iocoder.yudao.module.worker.service.clerkfans.ClerkFansService;
import cn.iocoder.yudao.module.worker.service.clerklevel.ClerkLevelService;
import cn.iocoder.yudao.module.worker.service.trend.WorkerTrendService;
import com.alibaba.fastjson.JSON;
import org.apache.commons.lang3.StringUtils;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
import org.springframework.validation.annotation.Validated;
import io.swagger.v3.oas.annotations.tags.Tag;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.Operation;
import javax.validation.*;
import javax.servlet.http.*;
import java.util.*;
import java.io.IOException;

import cn.iocoder.yudao.framework.common.pojo.PageParam;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;

import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils;

import cn.iocoder.yudao.framework.apilog.core.annotation.ApiAccessLog;
import static cn.iocoder.yudao.framework.apilog.core.enums.OperateTypeEnum.*;
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.*;
import static cn.iocoder.yudao.framework.common.util.servlet.ServletUtils.getClientIP;
import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId;

import cn.iocoder.yudao.module.worker.controller.app.clerk.vo.*;
import cn.iocoder.yudao.module.worker.dal.dataobject.clerk.ClerkDO;
import cn.iocoder.yudao.module.worker.service.clerk.ClerkService;

@Tag(name = "用户 APP - 店员信息")
@RestController
@RequestMapping("/worker/clerk")
@Validated
public class AppClerkController {

    @Resource
    private ClerkService clerkService;

    @Resource
    private ClerkLevelService clerkLevelService;

    @Resource
    private ClerkFansService clerkFansService;

    @Resource
    private WorkerTrendService workerTrendService;

    @Resource
    private CategoryApi categoryApi;

    @Resource
    private ProductCommentApi productCommentApi;

    @PostMapping("/create")
    @Operation(summary = "创建店员信息")
    public CommonResult<Long> createClerk(@Valid @RequestBody AppClerkSaveReqVO createReqVO) {
        return success(clerkService.createClerk(createReqVO));
    }

    @PutMapping("/update")
    @Operation(summary = "更新店员信息")
    public CommonResult<Boolean> updateClerk(@Valid @RequestBody AppClerkSaveReqVO updateReqVO) {
        clerkService.updateClerk(updateReqVO);
        return success(true);
    }

    @DeleteMapping("/delete")
    @Operation(summary = "删除店员信息")
    @Parameter(name = "id", description = "编号", required = true)
    public CommonResult<Boolean> deleteClerk(@RequestParam("id") Long id) {
        clerkService.deleteClerk(id);
        return success(true);
    }

    @GetMapping("/get")
    @Operation(summary = "获得店员信息")
    public CommonResult<AppClerkRespVO> getClerk(@Valid AppClerkSaveReqVO createReqVO) {
        ClerkDO clerk = clerkService.getClerk(createReqVO.getId());
        ClerkLevelDO clerkLevelDO = clerkLevelService.getClerkLevel(clerk.getWorkerClerkLevelId());
        AppClerkRespVO appClerkRespVO = BeanUtils.toBean(clerk, AppClerkRespVO.class);
        appClerkRespVO.setCategoryNameList(getAppCategoryNameList(clerk.getCategoryIdArray()));
        appClerkRespVO.setClerkLevel(clerkLevelDO);

        // 查询关注列表
        List<ClerkFansDO> clerkFansList = clerkFansService.getClerkFansList(createReqVO.getUserId(), Convert.toSet(Long.class, createReqVO.getId()));
        Map<Long, ClerkFansDO> mapFans = convertMap(clerkFansList, ClerkFansDO::getWorkerClerkId);
        appClerkRespVO.setIsFans(ObjectUtil.isNotNull(mapFans.get(createReqVO.getId())));

        // 统计动态数量
        Integer trendNum = workerTrendService.getTrendNum(createReqVO.getId());
        appClerkRespVO.setTrendNum(trendNum);

        // 统计评论数量
        Integer commentNum = productCommentApi.getCommentNum(createReqVO.getId());
        appClerkRespVO.setCommentNum(commentNum);

        List<CategoryRespVO> goodsList = clerkService.getAppGoodsList(createReqVO.getId());
        appClerkRespVO.setGoodsList(goodsList);
        return success(appClerkRespVO);
    }

    @GetMapping("/getClerkBlind")
    @Operation(summary = "获得店员盲盒")
    public CommonResult getClerkBlind() {
        Map<String, Object> data = new HashMap<>();
        List<ClerkLevelDO> clerkLevelList = clerkLevelService.getClerkLevelList();
        List<CategoryRespVO> goodsList = clerkService.getAppBlindGoodsList();

        data.put("clerkLevelList", clerkLevelList);
        data.put("goodsList", goodsList);
        return success(data);
    }

    @GetMapping("/getHomeData")
    @Operation(summary = "获得首页信息")
    public CommonResult<Map<String,Object>> getHomeData() {
        Map<String, Object> data = new HashMap<>();
        List<CategoryRespDTO> categoryList = categoryApi.getAppCategoryList(-1L);
        List<ClerkDO> clerkHotList = clerkService.getClerkHotList();
        List<ClerkDO> clerkNewList = clerkService.getClerkNewList();
        data.put("categoryList", categoryList);
        data.put("clerkHotList", clerkHotList);
        data.put("clerkNewList", clerkNewList);
        return success(data);
    }

    @GetMapping("/getWeekTopList")
    @Operation(summary = "获得榜单列表")
    public CommonResult<Map<String, List<ClerkDO>>> getWeekTopList() {
        Map<String, List<ClerkDO>> data = new HashMap<>();
        List<ClerkDO> maleWeekTopList = clerkService.getWeekTopList(SexEnum.MALE.getSex());
        List<ClerkDO> femaleWeekTopList = clerkService.getWeekTopList(SexEnum.FEMALE.getSex());
        data.put("maleWeekTopList", maleWeekTopList);
        data.put("femaleWeekTopList", femaleWeekTopList);
        return success(data);
    }

    @GetMapping("/getClerkList")
    @Operation(summary = "获得自己的店员列表")
    @PreAuthenticated
    public CommonResult<List<ClerkDO>> getClerkList() {
        List<ClerkDO> clerkList = clerkService.getClerkList(getLoginUserId());
        return success(clerkList);
    }

    @GetMapping("/page")
    @Operation(summary = "获得店员信息分页")
    public CommonResult<PageResult<AppClerkRespVO>> getClerkPage(@Valid AppClerkPageReqVO pageReqVO) {
        PageResult<ClerkDO> pageResult = clerkService.getClerkPage(pageReqVO);
        if (CollUtil.isEmpty(pageResult.getList())) {
            return success(PageResult.empty());
        }

        // 一级分类缓存
        Map<Long, CategoryRespDTO> list = categoryApi.getAppUserMap(-1L);

        // 二级分类缓存
        Map<Long, CategoryRespDTO> categoryMap = new HashMap<>();
        if(StringUtils.isNotBlank(pageReqVO.getCategoryId())){
            CategoryRespDTO category = categoryApi.getCategoryById(Long.parseLong(pageReqVO.getCategoryId()));
            if(category.getParentId() > 0){
                categoryMap = categoryApi.getUserMap(category.getParentId());
            }
        }

        PageResult<AppClerkRespVO> page = BeanUtils.toBean(pageResult, AppClerkRespVO.class);

        List<ClerkLevelDO> clerkLevelList = clerkLevelService.getClerkLevelListByIds(convertList(page.getList(), AppClerkRespVO::getWorkerClerkLevelId));
        Map<Long, ClerkLevelDO> clerkLevelMap = convertMap(clerkLevelList, ClerkLevelDO::getId);

        for(AppClerkRespVO clerk : page.getList()){
            if(StringUtils.isNotBlank(clerk.getCategoryIdArray())){
                List<String> categoryNameList = new ArrayList<>();

                // 一级分类
                if(StringUtils.isNotBlank(pageReqVO.getCategoryId())){
                    CategoryRespDTO category = categoryApi.getCategoryById(Long.parseLong(pageReqVO.getCategoryId()));
                    if(category.getParentId() > 0){
                        CategoryRespDTO categoryRespDTO = list.get(category.getParentId());
                        if(categoryRespDTO != null){
                            categoryNameList.add(categoryRespDTO.getName());
                        }
                    }else{
                        List<Long> categoryIdList = JSON.parseArray(clerk.getCategoryIdArray(), Long.class);
                        for(Long categoryId : categoryIdList){
                            CategoryRespDTO categoryRespDTO = list.get(categoryId);
                            if(categoryRespDTO != null){
                                categoryNameList.add(categoryRespDTO.getName());
                            }
                        }
                    }
                }else{
                    List<Long> categoryIdList = JSON.parseArray(clerk.getCategoryIdArray(), Long.class);
                    for(Long categoryId : categoryIdList){
                        CategoryRespDTO categoryRespDTO = list.get(categoryId);
                        if(categoryRespDTO != null){
                            categoryNameList.add(categoryRespDTO.getName());
                        }
                    }
                }

                // 二级分类
                List<Long> categoryIdList = JSON.parseArray(clerk.getCategoryIdArray(), Long.class);
                for(Long categoryId : categoryIdList){
                    CategoryRespDTO categoryDTO = categoryMap.get(categoryId);
                    if(categoryDTO != null){
                        categoryNameList.add(categoryDTO.getName());
                    }
                }

                clerk.setCategoryNameList(categoryNameList);
            }

            clerk.setClerkLevel(clerkLevelMap.getOrDefault(clerk.getWorkerClerkLevelId(), new ClerkLevelDO()));
        }
        return success(page);
    }

    @GetMapping("/export-excel")
    @Operation(summary = "导出店员信息 Excel")
    @ApiAccessLog(operateType = EXPORT)
    public void exportClerkExcel(@Valid AppClerkPageReqVO pageReqVO,
              HttpServletResponse response) throws IOException {
        pageReqVO.setPageSize(PageParam.PAGE_SIZE_NONE);
        List<ClerkDO> list = clerkService.getClerkPage(pageReqVO).getList();
        // 导出 Excel
        ExcelUtils.write(response, "店员信息.xls", "数据", AppClerkRespVO.class,
                        BeanUtils.toBean(list, AppClerkRespVO.class));
    }

    private List<String> getAppCategoryNameList(String categoryIdArray) {
        // 一级分类缓存
        Map<Long, CategoryRespDTO> list = categoryApi.getAppUserMap(-1L);
        List<String> categoryNameList = new ArrayList<>();
        if(StringUtils.isNotBlank(categoryIdArray)){
            List<Long> categoryIdList = JSON.parseArray(categoryIdArray, Long.class);
            for(Long categoryId : categoryIdList){
                CategoryRespDTO categoryRespDTO = list.get(categoryId);
                if(categoryRespDTO != null){
                    categoryNameList.add(categoryRespDTO.getName());
                }
            }
        }
        return categoryNameList;
    }

}